#include "D3D9Engine.h"


bool CD3D9Engine::Idle()
{
   MSG   message = {0};

   if(_appActive == false)
   {

      if(GetMessage(&message, NULL, 0, 0))
      {
         TranslateMessage(&message);
         DispatchMessage(&message);
      }

      return false;
   }
   else
   {
      while(PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
      {
         TranslateMessage(&message);
         DispatchMessage(&message);

         if(message.message == WM_QUIT)
         {
            _isRunning = false;
         }
      }

      return true;

   }

   return true;
}


LRESULT CALLBACK CD3D9Engine::StaticWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	CD3D9Engine* ptrApp = NULL;

	if(msg == WM_NCCREATE)
	{
		ptrApp = (CD3D9Engine*)((LPCREATESTRUCT)lParam)->lpCreateParams;
		SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)ptrApp);
	}
	else
	{
		ptrApp = (CD3D9Engine*)(GetWindowLongPtr(hWnd, GWL_USERDATA));
	}

	if(ptrApp)
	{
		ptrApp->_hwnd= hWnd;
		return ptrApp->RealWndProc(msg, wParam, lParam);
	}
	else
	{
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}
}


LRESULT CD3D9Engine::RealWndProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_CREATE:
			{
				_isRunning = true;
				ShowWindow(_hwnd, SW_SHOW);
				return 0;
			}
		case WM_ACTIVATE:
			{
				_appActive = true;
				return 0;
			}
		case WM_CLOSE:
			{
				_isRunning = false;
				return 0;
			}
		case WM_SIZE:
			{
				if(wParam == SIZE_MINIMIZED)
				{
					_appActive = false;
					ShowWindow(_hwnd, SW_MINIMIZE);
				}
				else
				{
					_appActive = true;

					if(wParam == SIZE_MAXIMIZED)
					{
						ToggleFullscreen();
					}
				}

				return 0;
			}

		case WM_SYSKEYUP:
		case WM_KEYUP:
			{
				if(wParam > 0 && wParam < 256)
				{
					if(_input)
					{
						_input->_keys[wParam] = false;
					}
				}
			
				return 0;
			}
			
		case WM_SYSKEYDOWN:
		case WM_KEYDOWN:
			{
				if(wParam > 0 && wParam < 256)
				{
					if(_input)
					{
						//_input->_keys[wParam] = true;
					}
				}

				return 0;
			}
		case WM_LBUTTONDOWN:
			{
				if(_input)
				{
					_input->_MouseButtonFlags |= CASGE_LBUTTON;
				}
			
				return 0;
			}
		case WM_SYSCHAR:
		case WM_CHAR:
			{
				if((wParam >= '0' && wParam <= '9') ||
					(wParam >= 'a' && wParam <= 'z') ||
					(wParam >= 'A' && wParam <= 'Z'))
				{
					if(_input)
					{
						if((lParam & 0xC0000000) == 0)
							_input->_keys[wParam] = true;
						else
							_input->_keys[wParam] = false;

					}
				}

				return 0;
			}
		case WM_LBUTTONUP:
			{
				if(_input)
				{
					_input->_MouseButtonFlags |= CASGE_LBUTTON;
				}

				return 0;
			}

		case WM_RBUTTONDOWN:
			{
				if(_input)
				{
					_input->_MouseButtonFlags |= CASGE_RBUTTON;
				}

				return 0;
			}

		case WM_RBUTTONUP:
			{
				if(_input)
				{
					_input->_MouseButtonFlags |= CASGE_RBUTTON;
				}

				return 0;
			}

		case WM_MOUSEMOVE:
			{
				if(_input)
				{
					_input->SetAbsMouseCoordinates((UINT)LOWORD(lParam), (UINT)HIWORD(lParam));
					_input->_MousePosX = (UINT)LOWORD(lParam);
					_input->_MousePosY = (UINT)HIWORD(lParam);
				}

				return 0;
			}
		case WM_INPUT:
			{
				if(_input == NULL ||
					wParam == RIM_INPUTSINK)
					return 0;

				UINT dwSize = 0;

				GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));

				LPBYTE rawdata = new BYTE[dwSize];

				if(GetRawInputData((HRAWINPUT)lParam, RID_INPUT, rawdata, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
				{
					delete[] rawdata;
					return 0;
				}

				RAWINPUT* raw = (RAWINPUT*)rawdata;
				bool fromBackg = (wParam == RIM_INPUTSINK);

				_input->Update(raw, 0, fromBackg);

				delete[] rawdata;
				return 0;
			}

		default:
			return DefWindowProc(_hwnd, msg, wParam, lParam);
	}
}